/*
 * Copyright 2020-2021 redragon.dongbin
 *
 * This file is part of redragon-erp/赤龙ERP.

 * redragon-erp/赤龙ERP is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.

 * redragon-erp/赤龙ERP is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.

 * You should have received a copy of the GNU General Public License
 * along with redragon-erp/赤龙ERP.  If not, see <https://www.gnu.org/licenses/>.
 */
package com.erp.prod.mrp.service.spring;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.redragon.framework.hibernate.data.SnowFlake;
import org.redragon.framework.hibernate.model.Pages;
import org.redragon.framework.util.ShiroUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.erp.common.inv.input.service.InvInputHeadService;
import com.erp.common.inv.stock.service.InvStockService;
import com.erp.hr.dao.model.HrStaffInfoRO;
import com.erp.hr.service.HrCommonService;
import com.erp.masterdata.common.service.MasterDataCommonService;
import com.erp.masterdata.material.dao.model.MdMaterial;
import com.erp.prod.bom.dao.model.ProdBomLine;
import com.erp.prod.bom.service.ProdBomHeadService;
import com.erp.prod.mps.dao.model.ProdMpsHead;
import com.erp.prod.mps.dao.model.ProdMpsLine;
import com.erp.prod.mps.service.ProdMpsHeadService;
import com.erp.prod.mps.service.ProdMpsLineService;
import com.erp.prod.mrp.dao.ProdMrpHeadDao;
import com.erp.prod.mrp.dao.ProdMrpLineDao;
import com.erp.prod.mrp.dao.model.ProdMrpHead;
import com.erp.prod.mrp.dao.model.ProdMrpHeadCO;
import com.erp.prod.mrp.dao.model.ProdMrpLine;
import com.erp.prod.mrp.service.ProdMrpBillRService;
import com.erp.prod.mrp.service.ProdMrpHeadService;
import com.erp.prod.mrp.service.ProdMrpLineService;

@Service
@Transactional(rollbackFor=Exception.class)
public class ProdMrpHeadServiceImpl implements ProdMrpHeadService {

    //注入Dao
    @Autowired
    private ProdMrpHeadDao prodMrpHeadDao;
    @Autowired
    private ProdMrpLineDao prodMrpLineDao;
    @Autowired
    private ProdMrpLineService prodMrpLineService;
    @Autowired
    private ProdMpsHeadService prodMpsHeadService;
    @Autowired
    private ProdMpsLineService prodMpsLineService;
    @Autowired
    private ProdBomHeadService prodBomHeadService;
    @Autowired
    private HrCommonService hrCommonService;
    @Autowired
    private MasterDataCommonService masterDataCommonService;
    @Autowired
    @Qualifier("invStockServiceCommon")
    private InvStockService invStockServiceCommon;
    @Autowired
    @Qualifier("invInputHeadServiceCommon")
    private InvInputHeadService invInputHeadServiceCommon;
    @Autowired
    private ProdMrpBillRService prodMrpPoaRService;
    
    @Override
    public void insertDataObject(ProdMrpHead obj) {
        this.prodMrpHeadDao.insertDataObject(obj);
    }

    @Override
    public void updateDataObject(ProdMrpHead obj) {
        this.prodMrpHeadDao.updateDataObject(obj);
    }
    
    @Override
    public void insertOrUpdateDataObject(ProdMrpHead obj) {
        this.prodMrpHeadDao.insertOrUpdateDataObject(obj);
    }

    @Override
    public void deleteDataObject(ProdMrpHead obj) {
        this.prodMrpHeadDao.deleteDataObject(obj);
        this.prodMrpLineService.deleteProdMrpLineByMrpHeadCode(obj.getMrpHeadCode());
        this.prodMrpPoaRService.deleteRelateByMrpHeadCode(obj.getMrpHeadCode());
    }

    @Override
    public List<ProdMrpHead> getDataObjects() {
        return this.prodMrpHeadDao.getDataObjects();
    }

    @Override
    public ProdMrpHead getDataObject(int id) {
        return this.prodMrpHeadDao.getDataObject(id);
    }

    @Override
    public ProdMrpHead getDataObject(String code) {
        return this.prodMrpHeadDao.getDataObject(code);
    }

    @Override
    public List<ProdMrpHead> getDataObjects(ProdMrpHeadCO paramObj) {
        return this.prodMrpHeadDao.getDataObjects(paramObj);
    }

    @Override
    public List<ProdMrpHead> getDataObjects(Pages pages) {
        return this.prodMrpHeadDao.getDataObjects(pages);
    }
    
    @Override
    public List<ProdMrpHead> getDataObjects(Pages pages, ProdMrpHeadCO paramObj) {
        return this.prodMrpHeadDao.getDataObjects(pages, paramObj);
    }
    
    @Override
    public List<Map<String, Object>> getDataObjectsArray(Pages pages, ProdMrpHeadCO paramObj) {
        return this.prodMrpHeadDao.getDataObjectsArray(pages, paramObj);
    }
    
    @Override
    public List<ProdMrpHead> getDataObjectsForDataAuth(String dataAuthSQL, Pages pages, ProdMrpHeadCO paramObj) {
        return this.prodMrpHeadDao.getDataObjectsForDataAuth(dataAuthSQL, pages, paramObj);
    }
    
    @Override
    public void updateApproveStatus(String code, String approveStatus) {
        this.prodMrpHeadDao.updateApproveStatus(code, approveStatus);
        
        if(approveStatus.equals("UNSUBMIT")) {
            //更新行表版本号
            this.prodMrpLineDao.updateLineForVersion(code);
            
        }
    }
    
    @Override
    public String autoCreateMrp(String billHeadCode) {
        List<ProdBomLine> prodBomLineList = new ArrayList<ProdBomLine>();
        
        //获取mps头数据
        ProdMpsHead prodMpsHead = this.prodMpsHeadService.getDataObject(billHeadCode);
        
        //获取mps行数据
        List<ProdMpsLine> prodMpsLineList = this.prodMpsLineService.getProdMpsLineListByMpsHeadCode(billHeadCode);
        
        //循环计划行,累加物料清单行
        for(ProdMpsLine prodMpsLine: prodMpsLineList) {
          //递归计算数量
            BigDecimal realQuantity = prodMpsLine.getPlanQuantity();
            //获取库存数量
            BigDecimal stockQuantity = this.invStockServiceCommon.getMaterialStockNumber(prodMpsLine.getMaterialCode());
            //获取预计接收数量
            BigDecimal willInputQuantity = this.invInputHeadServiceCommon.getInputQuantityForNotStock(prodMpsLine.getMaterialCode());
            //计算结果
            BigDecimal countQuantity = realQuantity.subtract(stockQuantity).subtract(willInputQuantity);
            //如果计算结果数量足够，则此物料跳过生成需求计划
            if(countQuantity.doubleValue()<=0) {
                continue;
            }
            
            //将主物料放入清单
            ProdBomLine prodBomLine = new ProdBomLine();
            prodBomLine.setMaterialCode(prodMpsLine.getMaterialCode());
            prodBomLine.setMpsLineCode(prodMpsLine.getMpsLineCode());
            prodBomLine.setPlanStartDate(prodMpsLine.getPlanStartDate());
            prodBomLine.setPlanEndDate(prodMpsLine.getPlanEndDate());
            prodBomLine.setCountQuantity(prodMpsLine.getPlanQuantity());
            prodBomLineList.add(prodBomLine);
            
            //获取当前物料的结构清单
            List<ProdBomLine> prodBomLineListTemp = new ArrayList<ProdBomLine>();
            prodBomLineListTemp = this.prodBomHeadService.getBomMaterialList(prodBomLineListTemp, prodMpsLine.getMaterialCode(), countQuantity, BigDecimal.ZERO, prodMpsLine.getPlanEndDate(), prodMpsLine.getMpsLineCode());
            prodBomLineList.addAll(prodBomLineListTemp);
        }
        
        //创建物料需求计划头
        ProdMrpHead prodMrpHead = new ProdMrpHead();
        //设置职员信息
        HrStaffInfoRO staffInfo = this.hrCommonService.getStaffInfo(ShiroUtil.getPrincipal());
        prodMrpHead.setStaffCode(staffInfo.getStaffCode());
        prodMrpHead.setDepartmentCode(staffInfo.getDepartmentCode());
        prodMrpHead.setMpsHeadCode(prodMpsHead.getMpsHeadCode());
        prodMrpHead.setMrpHeadCode(prodMpsHead.getMpsHeadCode()+"_MRP");
        prodMrpHead.setMrpName(prodMpsHead.getMpsName()+"_MRP");
        //插入需求计划头
        this.prodMrpHeadDao.insertDataObject(prodMrpHead);
        
        //根据物料清单循环计算物料需求计划行
        for(ProdBomLine prodBomLine: prodBomLineList) {
            //获取物料数据
            MdMaterial mdMaterial = this.masterDataCommonService.getMdMaterialInfoCache(prodBomLine.getMaterialCode());
            
            ProdMrpLine prodMrpLine = new ProdMrpLine();
            prodMrpLine.setPlanQuantity(prodBomLine.getCountQuantity());
            prodMrpLine.setPlanStartDate(prodBomLine.getPlanStartDate());
            prodMrpLine.setPlanEndDate(prodBomLine.getPlanEndDate());
            prodMrpLine.setBomProperty(mdMaterial.getBomProperty());
            prodMrpLine.setMaterialCode(prodBomLine.getMaterialCode());
            prodMrpLine.setMpsLineCode(prodBomLine.getMpsLineCode());
            prodMrpLine.setMrpHeadCode(prodMrpHead.getMrpHeadCode());
            prodMrpLine.setMrpLineCode(SnowFlake.getConcurrentId().toString());
            
            //插入需求计划行
            this.prodMrpLineService.insertDataObject(prodMrpLine);
        }
        
        //返回json数据
        return "{\"errCode\":0, \"errMsg\": \"\", \"mrpHeadId\": "+prodMrpHead.getMrpHeadId()+", \"mrpHeadCode\": \""+prodMrpHead.getMrpHeadCode()+"\"}";
    
    }
    
    @Override
    public boolean isExistMrpRelateMps(String mpsHeadCode) {
        return this.prodMrpHeadDao.isExistMrpRelateMps(mpsHeadCode);
    }
    
}